home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / rpg / crossfir.92 / crossfir / crossfire-0.92.5 / crossedit / Attr.c < prev    next >
C/C++ Source or Header  |  1996-07-24  |  26KB  |  1,026 lines

  1. /*
  2.     Copyright (C) 1993 Jarkko Sonninen & Petri Heinila
  3.  
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 2 of the License, or
  7.     (at your option) any later version.
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU General Public License
  15.     along with this program; if not, write to the Free Software
  16.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.     
  18.     The authors can be reached via e-mail to Jarkko.Sonninen@lut.fi
  19.     or Petri.Heinila@lut.fi .
  20. */
  21.  
  22.  
  23.  
  24. #include "Posix.h"
  25. #include "Attr.h"
  26. #include "X11.h"
  27. #include "CrList.h"
  28. #include "CrFace.h"
  29. #include "CrEdit.h"
  30. #include "Cnv.h"
  31. #include "Edit.h"
  32. #include "App.h"
  33. #include "loader.h"
  34. #include "debug.h"
  35.  
  36. static void AttrReset(Attr self);
  37.  
  38. /* variables, combination bit */
  39. #define T_Path      (1<<I_Path)
  40. #define T_X         (1<<I_X)
  41. #define T_Y         (1<<I_Y)
  42. #define T_Weight    (1<<I_Weight)
  43. #define T_Connect   (1<<I_Connect)
  44. #define T_Hp        (1<<I_Hp)
  45. #define T_Trigger   (1<<I_Trigger)
  46. #define T_Sacrifice (1<<I_Sacrifice)
  47. #define T_Count     (1<<I_Count)
  48. #define T_Lockcode  (1<<I_Lockcode) /* slaying - field */
  49. #define T_Direction (1<<I_Direction)
  50. #define T_Rotation  (1<<I_Rotation)
  51. #define T_NoPick    (1<<I_NoPick)
  52. #define T_Unique    (1<<I_Unique)
  53. #define T_WeightL   (1<<I_WeightL)
  54. #define T_Brand     (1<<I_Brand)
  55.  
  56. /*** types ar Combinations ***/
  57. #define T_Exit      (T_Path | T_X | T_Y )
  58. #define T_Trapdoor  (T_Weight | T_X | T_Y )
  59. #define T_Connected (T_Connect )
  60. #define T_Pit       (T_Connect | T_X | T_Y )
  61. #define T_Monster   (T_Hp )
  62. #define T_Pedestal  (T_Connected | T_Trigger )
  63. #define T_Altar     (T_Connected | T_Sacrifice | T_Count )
  64. #define T_Button    (T_Weight | T_Connected)
  65. #define T_Director  (T_Connected | T_Direction | T_Rotation)
  66. #define T_Lockdoor  (T_Lockcode)
  67. #define T_Key       (T_Lockcode | T_Unique)
  68. #define T_Container (T_Lockcode | T_WeightL | T_Brand | T_Unique | T_NoPick)
  69. #define T_Sign      0
  70. #define T_Map       (T_X | T_Y | T_Path)
  71.  
  72. #define T_Default   0
  73.  
  74. /*
  75.  * transfer type from game to editor, return negative on error
  76.  */
  77. int GetType (object *tmp)
  78. {
  79.     if (!tmp)
  80.     return (-1);
  81.  
  82.     if (tmp->head)
  83.     tmp = tmp->head;
  84.  
  85.     switch (tmp->type) {
  86.     case TELEPORTER:
  87.     case EXIT:
  88.     return T_Exit;
  89.     case TRAPDOOR:
  90.     return T_Trapdoor;
  91.     case HOLE:
  92.     return T_Pit;
  93.     case BUTTON:
  94.     case TRIGGER_BUTTON:
  95.     return T_Button;
  96.     case GATE:
  97.     case HANDLE:
  98.     case TIMED_GATE:
  99.     case MAGIC_EAR:
  100.     case TRIGGER:
  101.     return T_Connected;
  102.     case ALTAR:
  103.     case TRIGGER_ALTAR:
  104.     return T_Altar;
  105.     case PEDESTAL:
  106.     case TRIGGER_PEDESTAL:
  107.     return T_Pedestal;
  108.     case BOOK:
  109.     case SIGN:
  110.     return T_Sign;
  111.     case LOCKED_DOOR:
  112.     return T_Lockdoor;
  113.     case SPECIAL_KEY:
  114.     return T_Key;
  115.     case MAP: /* shouldn't happen ... */
  116.     return T_Map;
  117.     case DIRECTOR:
  118.     case FIREWALL:
  119.     return (tmp->arch->animations > 0) ? T_Director : T_Default;
  120.     case CONTAINER:
  121.     return T_Container;
  122.     default:
  123.     if (QUERY_FLAG(tmp, FLAG_MONSTER))
  124.         return T_Monster;
  125.     else
  126.         return T_Default;
  127.     }
  128.     /* return -1; */
  129. }
  130.  
  131. /**********************************************************************
  132.  *Section: get value from object for displying
  133.  *Commentary:
  134.  * Remeber, the strings from obejct may be NULL's
  135.  **********************************************************************/
  136.  
  137. static void getX (object *ob, char *str, XtPointer c) {
  138.     sprintf(str,"%d",EXIT_X(ob));
  139. }
  140.  
  141. static void getY (object *ob, char *str, XtPointer c) {
  142.     sprintf(str,"%d",EXIT_Y(ob));
  143. }
  144.  
  145. static void getPath (object *ob, char *str, XtPointer c) {
  146.     strcpy (str, EXIT_PATH(ob) ? EXIT_PATH(ob) : "");
  147. }
  148.  
  149. static void getWeight (object *ob, char *str, XtPointer c) {
  150.     sprintf(str,"%ld",ob->weight);
  151. }
  152.  
  153. /*** connected ***/
  154. static void getConnect (object *ob, char *str, XtPointer c) {
  155.     sprintf(str,"%d",get_button_value(ob));
  156. }
  157.  
  158. static void getHp (object *ob, char *str, XtPointer c) {
  159.     sprintf(str,"%d",ob->stats.hp);
  160. }
  161.  
  162. #define NotUsed "(not-used)"
  163.  
  164. static void getTrigger (object *ob, char *str, XtPointer c) {
  165.     if(!ob->slaying || !*ob->slaying) 
  166.     sprintf(str,NotUsed);
  167.     else
  168.     strcpy (str, ob->slaying);
  169. }
  170.  
  171. /*** sacriface ***/
  172. static void getSacrifice (object *ob, char *str, XtPointer c) {
  173.     if(!ob->slaying || !*ob->slaying) {
  174.     if(!ob->arch->clone.slaying)
  175.         LOG(llevError,"missing sacriface for altar");
  176.     strcpy (str, ob->arch->clone.slaying);
  177.     } else
  178.     strcpy (str, ob->slaying);
  179. }
  180.  
  181. static void getCount (object *ob, char *str, XtPointer c) {
  182.     sprintf(str,"%d",ob->stats.food);
  183. }
  184.  
  185. /*** lockcode ***/
  186. static void getLockcode (object *ob, char *str, XtPointer c) {
  187.     if(!ob->slaying || !*ob->slaying) {
  188.     sprintf(str,NotUsed);
  189.     } else
  190.     strcpy (str, ob->slaying);
  191. }
  192.  
  193. /*** direction ***/
  194. static void getDirection (object *ob, char *str, XtPointer c) {
  195.     sprintf(str,"%d",ob->stats.maxsp);
  196. }
  197.  
  198. /*** rotation ***/
  199. static void getRotation (object *ob, char *str, XtPointer c) {
  200.     sprintf(str,"%d",ob->stats.sp);
  201. }
  202.  
  203. /*** unique ***/
  204. static void getUnique (object *ob, char *str, XtPointer c) {
  205.     *str = QUERY_FLAG(ob, FLAG_UNIQUE) ? ~0 : 0;
  206. }
  207.  
  208. /*** no pick ***/
  209. static void getNoPick (object *ob, char *str, XtPointer c) {
  210.     *str = QUERY_FLAG(ob, FLAG_NO_PICK) ? ~0 : 0;
  211. }
  212.  
  213. /*** weight limit ***/
  214. static void getWeightL (object *ob, char *str, XtPointer c) {
  215.     sprintf(str,"%ld",ob->weight_limit);
  216. }
  217.  
  218. /*** brand ***/
  219. static void getBrand (object *ob, char *str, XtPointer c) {
  220.     if(!ob->race || !*ob->race) 
  221.     sprintf(str,NotUsed);
  222.     else
  223.     sprintf(str,"%s",ob->race);
  224. }
  225.  
  226. /*
  227.  * putValue functions
  228.  *
  229.  */
  230.  
  231. /*** coord ***/
  232. static void putX (object *ob, char *str, XtPointer c) {
  233.     EXIT_X(ob) = atoi(str);
  234. }
  235.  
  236. static void putY (object *ob, char *str, XtPointer c) {
  237.     EXIT_Y(ob) = atoi(str);
  238. }
  239.  
  240. /*** path ***/
  241. static void putPath (object *ob, char *str, XtPointer c) {
  242.     if(EXIT_PATH(ob)) free_string(EXIT_PATH(ob));
  243.     EXIT_PATH(ob) = NULL;
  244.     if(strlen(str)) EXIT_PATH(ob) = add_string(str);
  245. }
  246.  
  247. /*** sacrifice ***/
  248. static void putSacrifice (object *ob, char *str, XtPointer c) {
  249.     if(ob->slaying) free_string(ob->slaying);
  250.     ob->slaying = add_string(str);
  251. }
  252.  
  253. /*** trigger ***/
  254. static void putTrigger (object *ob, char *str, XtPointer c) {
  255.     if(!strcmp(str,NotUsed))
  256.     ob->slaying = NULL;
  257.     else {
  258.     if(ob->slaying) free_string(ob->slaying);
  259.     ob->slaying = add_string(str);
  260.     }
  261. }
  262.  
  263. /*** weight ***/
  264. static void putWeight (object *ob, char *str, XtPointer c) {
  265.     ob->weight = atoi(str);
  266. }
  267.  
  268. /*** connect ***/
  269. static void putConnect (object *ob, char *str, XtPointer c) {
  270.     if (QUERY_FLAG(ob, FLAG_IS_LINKED))
  271.     remove_button_link(ob);
  272.     add_button_link(ob, ob->map, atoi(str));
  273. }
  274.  
  275. /*** hp ***/
  276. static void putHp (object *ob, char *str, XtPointer c) {
  277.     ob->stats.hp = atoi(str);
  278. }
  279.  
  280. /*** count ***/
  281. static void putCount (object *ob, char *str, XtPointer c) {
  282.     ob->stats.food = atoi(str);
  283. }
  284.  
  285. /*** lockcode ***/
  286. static void putLockcode (object *ob, char *str, XtPointer c) {
  287.     if(!strcmp(str,NotUsed))
  288.        ob->slaying = NULL;
  289.     else {
  290.     if(ob->slaying) free_string(ob->slaying);
  291.     ob->slaying = add_string(str);
  292.     }
  293. }
  294.  
  295. /*** direction ***/
  296. static void putDirection (object *ob, char *str, XtPointer c) {
  297.     ob->stats.maxsp = atoi(str);
  298.     animate_object (ob);
  299. }
  300.  
  301. /*** rotation ***/
  302. static void putRotation (object *ob, char *str, XtPointer c) {
  303.     ob->stats.sp = atoi(str);
  304.     animate_object (ob);
  305. }
  306.  
  307. /*** unique ***/
  308. static void putUnique (object *ob, char *str, XtPointer c) {
  309.     *str ? SET_FLAG(ob, FLAG_UNIQUE) : CLEAR_FLAG(ob, FLAG_UNIQUE);
  310. }
  311.  
  312. /*** no pick ***/
  313. static void putNoPick (object *ob, char *str, XtPointer c) {
  314.     *str ? SET_FLAG(ob, FLAG_NO_PICK) : CLEAR_FLAG(ob, FLAG_NO_PICK);
  315. }
  316.  
  317. /*** weight limit ***/
  318. static void putWeightL (object *ob, char *str, XtPointer c) {
  319.        debug0("NO putWeightL\n");
  320. }
  321.  
  322. /*** brand ***/
  323. static void putBrand (object *ob, char *str, XtPointer c) {
  324.     if(!strcmp(str,NotUsed))
  325.     ob->race = NULL;
  326.     else {
  327.     if(ob->race) free_string(ob->race);
  328.     ob->race = add_string(str);
  329.     }
  330. }
  331.  
  332. /**********************************************************************
  333.  * tags
  334.  **********************************************************************/
  335.  
  336. AttrDef AttrDescription[] = {
  337.     {"Path",        TypeString, getPath,        putPath},
  338.     {"X",        TypeString, getX,        putX},
  339.     {"Y",        TypeString, getY,        putY},
  340.     {"Weight",        TypeString, getWeight,        putWeight},
  341.     {"Connect",        TypeString, getConnect,        putConnect},
  342.     {"Hp",        TypeString, getHp,        putHp},
  343.     {"Trigger",        TypeString, getTrigger,        putTrigger},
  344.     {"Sacrifice",    TypeString, getSacrifice,    putSacrifice},
  345.     {"Count",        TypeString, getCount,        putCount},
  346.     {"Lockcode",    TypeString, getLockcode,    putLockcode},
  347.     {"Direction",    TypeString, getDirection,    putDirection},
  348.     {"Rotation",    TypeString, getRotation,    putRotation},
  349.     {"No Pick",            TypeToggle, getNoPick,        putNoPick},
  350.     {"Unique",            TypeToggle, getUnique,        putUnique},
  351.     {"WeightL",            TypeString, getWeightL,        putWeightL},
  352.     {"Brand",            TypeString, getBrand,        putBrand},
  353.     {NULL,        0,        0}
  354. };
  355.  
  356. char *allowed_variables[] = {
  357.  
  358.     "name","race","slaying","other_arch",
  359.     "last_heal","last_sp","last_eat",
  360.     "speed","speed_left","slow_move",
  361.     "face","Str","Dex","Con","Wis","Cha","Int","Pow","hp","maxhp","sp","maxsp",
  362.     "exp","food","dam","wc","ac","nrof","level","direction",
  363.     "type","material","value","weight","carrying",
  364.     "immune","protected","attacktype","vulnerable",
  365.     "path_attuned","path_repelled","path_denied",
  366.     "invisible","magic","state","alive","applied","unpaid","need_an","need_ie",
  367.     "no_pick","no_pass","walk_on","walk_off","fly_on","fly_off",
  368.     "flying","monster","friendly","generator","auto_apply","treasure",
  369.     "apply_once","see_invisible","can_roll","is_turning","is_turnable",
  370.     "is_used_up","identified","reflecting","changing","splitting","hitback",
  371.     "startequip","blocksview","undead","scared","unaggressive",
  372.     "reflect_missile","reflect_spell","no_magic",
  373.     "wiz","was_wiz","tear_down","luck","run_away","pass_thru",
  374.     "can_pass_thru","pick_up","anim_speed","container","no_drop",
  375.     "no_pretext","will_apply","random_movement","can_apply",
  376.     "can_cast_spell","can_use_scroll","can_use_wand","can_use_bow",
  377.     "can_use_armour","can_use_weapon","can_use_ring","has_ready_wand",
  378.     "has_ready_bow","xrays","is_floor","lifesave","no_strength",
  379.     "sleep","stand_still","random_move","only_attack","armour",
  380.     "attack_movement", "move_state","confused","stealth","connected",
  381.     "cursed","damned","see_anywhere","known_magical","known_cursed",
  382.     "can_steal","been_applied","title", "has_ready_rod","can_use_rod",
  383.     "has_ready_horn","can_use_horn","expmul",
  384.     "unique","make_invisible",
  385.     "is_wooded","is_hilly","has_ready_skill","has_ready_weapon",
  386.     "no_skill_ident","glow_radius","is_blind","can_see_in_dark",
  387.     "is_cauldron",
  388. #ifdef NPC_PROG
  389.     "npc_status", "npc_program", 
  390. #endif
  391. };
  392.  
  393. #define ALLOWED_VARIABLES (sizeof(allowed_variables) / sizeof (char *))
  394.  
  395. /**********************************************************************
  396.  * widgets
  397.  **********************************************************************/
  398.  
  399. /*
  400.  * member: create tag widgets
  401.  * parent: parent container
  402.  */
  403. static void AttrTagsCreate(Attr self,Widget parent)
  404. {
  405.     int i;
  406.     self->attrnumber = 0;
  407.     while (self->desc[self->attrnumber].label)
  408.     self->attrnumber++;
  409.     
  410.     self->tags = (AttrTags*)XtCalloc(self->attrnumber,sizeof(AttrTags));
  411.     for(i=0; i < self->attrnumber; i++) {
  412.     if (self->desc[i].type == TypeString) {
  413.         self->tags[i].cont = XtVaCreateWidget
  414.         ("box",boxWidgetClass,parent,
  415.          XtNorientation,XtorientHorizontal,
  416.          NULL);
  417.         XtVaCreateManagedWidget
  418.         ("label",labelWidgetClass,self->tags[i].cont,
  419.          XtNlabel,self->desc[i].label,
  420.          NULL);
  421.         self->tags[i].value = XtVaCreateManagedWidget
  422.         ("value",asciiTextWidgetClass,self->tags[i].cont,
  423.          XtNtype,XawAsciiString,
  424.          XtNeditType,XawtextEdit,
  425.          NULL);
  426.     }
  427.     } 
  428.     for(i=0; i < self->attrnumber; i++) {
  429.     if (self->desc[i].type == TypeToggle) {
  430.         self->tags[i].cont = XtVaCreateWidget
  431.         ("box",boxWidgetClass,parent,
  432.          XtNorientation,XtorientHorizontal,
  433.          NULL);
  434.  
  435.         self->tags[i].value = XtVaCreateManagedWidget
  436.         ("toggle",toggleWidgetClass, self->tags[i].cont,
  437.          XtNlabel,self->desc[i].label,
  438.          NULL);
  439.     }
  440.     }
  441. }
  442.  
  443.  
  444. /*
  445.  * callback: receive ok
  446.  */
  447. static void AttrOkCb(Widget w,XtPointer client,XtPointer call)
  448. {
  449.     Attr self = (Attr)client;
  450.  
  451.     AttrApply(self);
  452.     AttrDestroy (self);
  453. }
  454.  
  455. /*
  456.  * receive apply
  457.  */
  458. static void AttrApplyCb(Widget w,XtPointer client,XtPointer call)
  459. {
  460.   Attr self = (Attr)client;
  461.   AttrApply(self);
  462. }
  463.  
  464. /* 
  465.  * receive cancel
  466.  */
  467. static void AttrCancelCb(Widget w,XtPointer client,XtPointer call)
  468. {
  469.   Attr self = (Attr)client;
  470.  
  471.   AttrDestroy(self);
  472. }
  473.  
  474. /* 
  475.  * receive dump
  476.  */
  477. static void AttrDumpCb(Widget w,XtPointer client,XtPointer call)
  478. {
  479.   Attr self = (Attr)client;
  480.  
  481.   dump_object(self->op);
  482.   CnvBrowseShowString(self->dump,errmsg); 
  483. }
  484.  
  485. /**********************************************************************
  486.  * widget-message
  487.  **********************************************************************/
  488.  
  489.  
  490. static CrListNode AttrInventoryNext(XtPointer client,XtPointer call)
  491. {
  492.     Attr self = (Attr)client;
  493.     CrListNode retNode = (CrListNode)call;
  494.     static struct _CrListNode node;
  495.     object *op = NULL;
  496.  
  497.     if (!self->op)
  498.     return (CrListNode)NULL;
  499.  
  500.     if(retNode) { /* next */
  501.     op = ((object *)retNode->ptr)->below;
  502.     } else {      /* begin */
  503.     op = self->op->inv;
  504.     }
  505.  
  506.     if(op) { 
  507.     node.face = op->face; 
  508.     node.name = op->name;
  509.     node.ptr = (XtPointer)op;
  510.     return &node;
  511.     }
  512.     return (CrListNode)NULL;
  513. }
  514.  
  515. /*
  516.  * callback: insert object 
  517.  */
  518. static void InsertCb(Widget w,XtPointer client,XtPointer call)
  519. {
  520.     Attr self = (Attr)client;
  521.     /* CrListCall ret = (CrListCall)call; */
  522.     object *obj;
  523.  
  524.     if((obj = AppItemGetObject(self->app)) && AttrGetObject(self)) {
  525.     debug1("Attr-InsertCb() %s\n",obj->name);
  526.     (void) insert_ob_in_ob(ObjectCreateClone(obj),AttrGetObject(self));
  527.     }
  528. }
  529.  
  530. /* 
  531.  * create recursively attributes from inventory
  532.  */
  533. static void AttrInventorySelectCb(Widget w,XtPointer client,XtPointer call)
  534. {
  535.     Attr self = (Attr)client;
  536.     CrListCall p = (CrListCall)call;
  537.     object *ob = (object *)p->node;
  538.  
  539.     if (self->attr) {
  540.     AttrDestroy (self->attr);
  541.     }
  542.  
  543.     self->attr = AttrCreate("attr",self->app, ob, 
  544.                 AttrDescription, GetType(ob), self->client);
  545. }
  546.  
  547. /*
  548.  * callback: delete object from look window
  549.  */
  550. static void DeleteCb(Widget w,XtPointer client,XtPointer call)
  551. {
  552.     Attr self = (Attr)client;
  553.     CrListCall ret = (CrListCall)call;
  554.     object *obj = ret->node;
  555.     
  556.     debug1("Attr-DeleteCb() %s\n",obj->name);
  557.     if (self->attr && self->attr->op == obj)
  558.     AttrDestroy (self->attr);
  559.     remove_ob(obj);
  560.     free_object(obj);
  561. }
  562.  
  563. /**********************************************************************
  564.  * widget - variables
  565.  **********************************************************************/
  566.  
  567. /*
  568.  *
  569.  */
  570. static void AttrVarSelectCb(Widget w,XtPointer client,XtPointer call)
  571. {
  572.     Attr self = (Attr)client;
  573.     XawListReturnStruct *ret = (XawListReturnStruct*)call;
  574.     XtVaSetValues(self->iw.var,
  575.           XtNstring,ret->string,
  576.           NULL);
  577.     XtPopdown(self->vars.shell);
  578. }
  579.  
  580. /*
  581.  *
  582.  */
  583. static void AttrVarCancelCb(Widget w,XtPointer client,XtPointer call)
  584. {
  585.     Attr self = (Attr)client;
  586.     XtPopdown(self->vars.shell);
  587. }
  588.  
  589. /*
  590.  * compare funtion for sorting in PathListGet()
  591.  */
  592. static int StrCmp (const void **s1, const void **s2)
  593. {
  594.     return strcmp (*s1, *s2);
  595. }
  596.  
  597. /*
  598.  * create widget layout for selectin variable from list
  599.  */
  600. static void AttrVarLayout(Attr self,Widget parent)
  601. {
  602.   Widget form,cancel,view;
  603.  
  604.   self->vars.shell = XtVaCreatePopupShell
  605.     ("vars",transientShellWidgetClass,parent,
  606.      NULL);
  607.   form = XtVaCreateManagedWidget
  608.     ("form",formWidgetClass,self->vars.shell,
  609.      NULL);
  610.   view = XtVaCreateManagedWidget
  611.     ("view",viewportWidgetClass,form,
  612.      NULL);
  613.   self->vars.list = XtVaCreateManagedWidget
  614.     ("list",listWidgetClass,view,
  615.      NULL);
  616.   XtAddCallback(self->vars.list,XtNcallback,AttrVarSelectCb,(XtPointer)self);
  617.   /*** sort varibales ***/
  618.  
  619.   qsort(allowed_variables, ALLOWED_VARIABLES,
  620.     sizeof(char *),(int (*)())StrCmp);
  621.  
  622.   XawListChange(self->vars.list,allowed_variables,
  623.         ALLOWED_VARIABLES, 0, True);
  624.   cancel = XtVaCreateManagedWidget
  625.     ("cancel",commandWidgetClass,form,
  626.      XtNfromVert,view,
  627.      NULL);
  628.   XtAddCallback(cancel,XtNcallback,AttrVarCancelCb,(XtPointer)self);
  629.   CnvCenterWidget(self->vars.shell);
  630. }
  631.  
  632. /*
  633.  *
  634.  */
  635. static void AttrVarGetCb(Widget w,XtPointer client,XtPointer call)
  636. {
  637.   Attr self = (Attr)client;
  638.   XtPopup(self->vars.shell,XtGrabExclusive);
  639. }
  640.  
  641. /**********************************************************************
  642.  * members
  643.  **********************************************************************/
  644.  
  645. static void Layout(Attr self,Widget parent, char *name)
  646. {
  647.     Widget form,view1,pane;
  648.     Widget ok,apply,cancel;
  649.     Widget view;
  650.  
  651.     self->shell = XtVaCreatePopupShell
  652.     (name, topLevelShellWidgetClass, parent, NULL);
  653.     form = XtVaCreateManagedWidget("form",formWidgetClass,self->shell,NULL);
  654.  
  655.     self->iw.name = XtVaCreateManagedWidget
  656.     ("name",asciiTextWidgetClass,form,
  657.      XtNtype,XawAsciiString,
  658.      XtNeditType,XawtextEdit,
  659.      XtNresize,False,
  660.      XtNadjust,False,
  661.      NULL);
  662.  
  663.     self->iw.face = XtVaCreateManagedWidget
  664.     ("face",crFaceWidgetClass,form,
  665.      XtNfromVert,self->iw.name,
  666.      XtNresize,True,
  667.      XtNadjust,False,
  668.      XtNobject,self->op,
  669.      NULL);
  670.  
  671.     /*** dump ***/
  672.     self->iw.exact = XtVaCreateManagedWidget
  673.     ("exact",commandWidgetClass,form,
  674.      XtNfromVert,self->iw.face,
  675.      XtNresize,True,
  676.      XtNadjust,False,
  677.      NULL);
  678.     XtAddCallback(self->iw.exact,XtNcallback,AttrDumpCb,(XtPointer)self);
  679.  
  680.     /*** inventory ***/
  681.     view = XtVaCreateManagedWidget
  682.     ("inventory",viewportWidgetClass,form,
  683.      XtNfromVert,self->iw.name,
  684.      XtNfromHoriz,self->iw.face,
  685.      NULL);
  686.     
  687.     self->iw.inv = XtVaCreateManagedWidget
  688.     ("list",crListWidgetClass,view,
  689.      XtNpackage, self,
  690.      XtNnext, AttrInventoryNext,
  691.      NULL);
  692.     XtAddCallback(self->iw.inv,XtNselectCallback,AttrInventorySelectCb,
  693.           (XtPointer)self);
  694.     XtAddCallback(self->iw.inv,XtNinsertCallback,InsertCb,
  695.           (XtPointer)self);
  696.     XtAddCallback(self->iw.inv,XtNdeleteCallback,DeleteCb,
  697.           (XtPointer)self);
  698.     
  699.     /*** multi ***/
  700.     view1 = XtVaCreateManagedWidget
  701.     ("view",viewportWidgetClass,form,
  702.      /*XtNallowVert,True,*/
  703.      XtNforceBars,True,
  704.      XtNfromVert,self->iw.exact,
  705.      NULL);
  706.     pane = XtVaCreateManagedWidget
  707.     ("pane",boxWidgetClass,view1,
  708.      XtNorientation,XtorientVertical,
  709.      NULL);
  710.  
  711.     /*** variable setting ***/
  712.     AttrVarLayout(self,parent);
  713.  
  714.     self->iw.msg = XtVaCreateManagedWidget
  715.     ("msg",asciiTextWidgetClass,form,
  716.      XtNtype,XawAsciiString,
  717.      XtNeditType,XawtextEdit,
  718.      XtNfromHoriz,NULL,
  719.      XtNfromVert,view1,
  720.      NULL);
  721.  
  722.  
  723.   self->iw.vars = XtVaCreateManagedWidget
  724.     ("vars",commandWidgetClass,form,
  725.      XtNfromVert,self->iw.msg,
  726.      NULL);
  727.   XtAddCallback(self->iw.vars,XtNcallback,AttrVarGetCb,(XtPointer)self);
  728.   self->iw.var = XtVaCreateManagedWidget
  729.     ("var",asciiTextWidgetClass,form,
  730.      XtNfromHoriz,self->iw.vars,
  731.      XtNfromVert,self->iw.msg,
  732.      XtNtype,XawAsciiString,
  733.      XtNeditType,XawtextEdit,
  734.      NULL);
  735.  
  736.   /*** reponses ***/
  737.   ok = XtVaCreateManagedWidget
  738.     ("ok",commandWidgetClass,form,
  739.      XtNfromVert,self->iw.vars,
  740.      NULL);
  741.   XtAddCallback(ok,XtNcallback,AttrOkCb,(XtPointer)self);
  742.   apply = XtVaCreateManagedWidget
  743.     ("apply",commandWidgetClass,form,
  744.      XtNfromVert,self->iw.vars,
  745.      XtNfromHoriz,ok,
  746.      NULL);
  747.   XtAddCallback(apply,XtNcallback,AttrApplyCb,(XtPointer)self);
  748.   cancel = XtVaCreateManagedWidget
  749.     ("cancel",commandWidgetClass,form,
  750.      XtNfromVert,self->iw.vars,
  751.      XtNfromHoriz,apply,
  752.      NULL);
  753.   XtAddCallback(cancel,XtNcallback,AttrCancelCb,(XtPointer)self);
  754.  
  755.   AttrTagsCreate(self,pane);
  756. }
  757.  
  758. /*
  759.  * - create object attribute editor from given object
  760.  * - change values in future of given object
  761.  * - struct Attr don't have to be initialized, but have to be
  762.  *   allocated anyway.
  763.  * - create widgets & popup window
  764.  */
  765. Attr AttrCreate(char *name, App app, object *ob, 
  766.         AttrDef *desc, unsigned long flags, Edit edit)
  767. {
  768.   Attr self = (Attr) XtMalloc (sizeof(struct _Attr));
  769.  
  770.   if (ob->head)
  771.     ob = ob->head;
  772.   self->op = ob;
  773.   self->app = app;
  774.   self->client = edit;
  775.   self->attr = NULL;
  776.  
  777.   self->desc = desc;
  778.   Layout (self, self->app->shell, name);
  779.   AttrChange(self,self->op, flags, self->client);
  780.  
  781.   self->dump = CnvBrowseCreate("dump", self->app->shell, NULL);
  782.   XtPopup(self->shell,XtGrabNone);
  783.   self->isup = True;
  784.   return self;
  785. }
  786.  
  787. /*
  788.  * change object to another
  789.  */
  790. void AttrChange(Attr self,object *ob, unsigned long flags, Edit edit)
  791. {
  792.   char buf[BUFSIZ];
  793.   int i, mask = 1;
  794.  
  795.   if (!self)
  796.       return;
  797.  
  798.   if (self->attr)
  799.       AttrDestroy (self->attr);
  800.  
  801.   if (ob && ob->head)
  802.     ob = ob->head;
  803.   self->op = ob;
  804.  
  805.   if(!ob) {
  806.       AttrReset(self);
  807.       XtVaSetValues(self->shell,
  808.             XtNtitle,"",
  809.             NULL);
  810.        return;
  811.   }
  812.  
  813.   self->flags = flags;
  814.  
  815.   /*** name ***/
  816.   XtVaSetValues(self->iw.name,
  817.         XtNstring,self->op->name,
  818.         NULL);
  819.  
  820.   /*** object ***/
  821.   XtVaSetValues(self->iw.face,
  822.         XtNobject,self->op,
  823.         NULL);
  824.  
  825.   /*** message ***/
  826.   XtVaSetValues(self->iw.msg,
  827.         XtNstring,self->op->msg,
  828.         NULL);
  829.  
  830.   /*** inventory ***/
  831.   XtVaSetValues(self->iw.inv,
  832.         XtNpackage,self,
  833.         NULL);
  834.  
  835.   /* get attribute value */
  836.   for (i = 0; self->desc[i].label; i++, mask <<= 1)
  837.       if(self->flags & mask) {
  838.       self->desc[i].getValue (ob, buf, (XtPointer) self->client);    
  839.       if (self->desc[i].type == TypeString) {
  840.           XtVaSetValues(self->tags[i].value,
  841.                 XtNstring, buf,
  842.                 NULL);    
  843.       } else if (self->desc[i].type == TypeToggle) {
  844.           XtVaSetValues(self->tags[i].value,
  845.                 XtNstate, *buf ? TRUE : FALSE,
  846.                 NULL);    
  847.       }
  848.       }
  849.  
  850.   /*** update ***/
  851.   for(i=0; self->desc[i].label; i++) {
  852.       XtUnmanageChild(self->tags[i].cont);
  853.   }
  854.   for(i=0; self->desc[i].label; i++) {
  855.       if(self->flags & (1 << i)) {
  856.       XtManageChild(self->tags[i].cont);
  857.       }
  858.   }
  859.   sprintf(buf,"Attr: %s",self->op->name);
  860.   XtVaSetValues(self->shell,
  861.         XtNtitle,buf,
  862.         XtNiconName,buf,
  863.         NULL);
  864.   self->modified = False;
  865. }
  866.  
  867. static void AttrReset(Attr self)
  868. {
  869.     int i;
  870.     debug0("Attr-Reset()\n");
  871.     /*** name ***/
  872.     XtVaSetValues(self->iw.name,
  873.           XtNstring,NULL,
  874.           NULL);
  875.     /*** object ***/
  876.     XtVaSetValues(self->iw.face,
  877.           XtNobject,NULL,
  878.           NULL);
  879.     /*** message ***/
  880.     XtVaSetValues(self->iw.msg,
  881.           XtNstring,NULL,
  882.           NULL);
  883.     /*** inventory ***/
  884.     XtVaSetValues(self->iw.inv,
  885.           XtNpackage,self,
  886.           NULL);
  887.  
  888.     for(i=0; self->desc[i].label; i++) {
  889.     XtUnmanageChild(self->tags[i].cont);
  890.     }
  891. }
  892.  
  893. /*
  894.  * popdown window & destroy widgets
  895.  */
  896. void AttrDestroy(Attr self)
  897. {
  898.     Edit tmp;
  899.     Attr tmp2;
  900.  
  901.     if (self->attr)
  902.     AttrDestroy (self->attr);
  903.     XtDestroyWidget(self->shell);
  904.     XtFree((char*)self->tags);
  905.     self->isup = False;
  906.     CnvBrowseDestroy(self->dump);
  907.  
  908.     /* 
  909.      * dirty part:
  910.      * here we find out to what part this window belongs to.
  911.      * it may be:
  912.      *  - Attr of Look in App
  913.      *  - MapAttr in Edit
  914.      *  - Attr of other Attr (inventory)
  915.      */
  916.     
  917.     if (self == self->app->attr)
  918.     self->app->attr = NULL;
  919.     else {
  920.     for (tmp = self->app->edit; tmp; tmp = tmp->next)
  921.         if (self == tmp->mapattr) {
  922.         tmp->mapattr = NULL;
  923.         break;
  924.         }
  925.     if (!tmp) {
  926.         for (tmp2 = self->app->attr; tmp2; tmp2 = tmp2->attr)
  927.         if (self == tmp2->attr) {
  928.             tmp2->attr = NULL;
  929.             break;
  930.         }
  931. #ifdef DEBUG
  932.         if (!tmp2)
  933.         debug0 ("Cannot find origin of Attr!!\n");
  934. #endif
  935.     } 
  936.     }
  937.     XtFree((char*)self);
  938. }
  939.  
  940. /*
  941.  * member: store information from edited widget structure 
  942.  * to object structure
  943.  */
  944. void AttrApply(Attr self)
  945. {
  946.     String str,var;
  947.     object *ob;
  948.     char buf[BUFSIZ];
  949.     int len, i, mask;
  950.  
  951.     /* check out, that object exist */
  952.     if(!self->op) {
  953.     return;
  954.     }
  955.     
  956.     for(ob = self->op; ob; ob = ob->more) {
  957.     /*** variable ***/
  958.     XtVaGetValues(self->iw.var,
  959.               XtNstring,&var,
  960.               NULL);
  961.     if(var && *var) {
  962.         debug1("AttrApply(), %s\n",var);
  963.         for (i = 0; i < ALLOWED_VARIABLES; i++)
  964.         if (!strncmp (allowed_variables[i], var, 
  965.                   strlen(allowed_variables[i]))) {
  966.             if (set_variable(ob,var) == -1) {            
  967.             sprintf(buf,"%s: no such variable",var);
  968.             CnvNotify(buf,"Continue",NULL);
  969.             }
  970.             break;
  971.         }
  972.         if (i >= ALLOWED_VARIABLES) {
  973.         sprintf(buf,"%s: cannot set variable",var);
  974.         CnvNotify(buf,"Continue",NULL);
  975.         }
  976.     }
  977.     /*** name ***/
  978.     XtVaGetValues(self->iw.name,
  979.               XtNstring,&str,
  980.               NULL);
  981.     if(ob->name) free_string(ob->name);
  982.     ob->name = add_string(str);
  983.     
  984.     /*** message ***/
  985.     XtVaGetValues(self->iw.msg,
  986.               XtNstring,&str,
  987.               NULL);
  988.     
  989.     if(self->op->msg) free_string(self->op->msg);
  990.     if((len = strlen(str))) {
  991.         if(str[len-1] != '\n') str[len-1] = '\n'; /*** kludge ***/
  992.         self->op->msg = add_string(str);
  993.     } else {
  994.         self->op->msg = NULL;
  995.     }
  996.  
  997.     /* set individual attribute value */
  998.     for (i = 0, mask = 1; self->desc[i].label; i++, mask <<= 1) {
  999.         if(self->flags & mask) {
  1000.         if (self->desc[i].type == TypeString) {
  1001.             XtVaGetValues(self->tags[i].value, XtNstring, &str, NULL);
  1002.             self->desc[i].putValue (ob, str, (XtPointer)self->client);
  1003.         } else if (self->desc[i].type == TypeToggle) {
  1004.             Boolean tmp;
  1005.             XtVaGetValues(self->tags[i].value, XtNstate, &tmp, NULL);
  1006.             *str = tmp ? ~0 : 0;
  1007.             self->desc[i].putValue (ob, str, (XtPointer)self->client);
  1008.         }
  1009.         }
  1010.     }
  1011.     }
  1012.  
  1013.     /*** clear variables ***/
  1014.     XtVaSetValues(self->iw.var,XtNstring,NULL,NULL);
  1015.  
  1016.     /*** update ***/
  1017.     AppUpdate (self->app);
  1018.     
  1019.     self->modified = True;
  1020.     /*self->client->modified = True;*/
  1021.     EditModified(self->client);
  1022. }
  1023.  
  1024.  
  1025. /*** end of Attr.c ***/
  1026.